﻿using NiYo.ParserBuilder.Core.Hl7.Helpers;
using NiYo.ParserBuilder.Domain.Hl7.DataTypes;
using NiYo.ParserBuilder.Domain.Hl7.Enums;
using NiYo.ParserBuilder.Domain.Hl7.Segments;
using NiYo.ParserBuilder.Exceptions;

namespace NiYo.ParserBuilder.Domain.Hl7
{
    public abstract class Hl7Message : Message
    {
        private readonly MessageType _messageType;
        private readonly TriggerEvent _triggerEvent;

        /// <summary>
        /// Constructor initializes the .MessageHeader of the Message with incoming parameters
        /// </summary>
        /// <param name="messageType">The messageType (ADT, MFN, ...)</param>
        /// <param name="triggerEvent">The triggerEvent (A01, A02, M02, ...)</param>
        protected Hl7Message(MessageType messageType, TriggerEvent triggerEvent)
        {
            _messageType = messageType;
            _triggerEvent = triggerEvent;

            MessageHeader = new MessageHeader();
        }

        #region MSH

        private MessageHeader _messageHeader;

        /// <summary>
        /// Gets or sets the MessageHeader (MSH).
        /// </summary>
        /// <value>The MessageHeader.</value>
        public MessageHeader MessageHeader
        {
            get { return _messageHeader; }
            set
            {
                _messageHeader = value;

                var messageStructure = MessageStructureHelper.GetMessageStructure(_triggerEvent)
                                       ?? string.Format("{0}_{1}", _messageType, _triggerEvent);

                // If there is a MessageType: check if it's valid. Otherwise, build a valid MessageType
                if (_messageHeader.MessageType != null)
                {
                    if (_messageHeader.MessageType.MessageTypeCode != _messageType)
                        throw new ParseException("The MessageHeader is not compatible with the current type of message.");
                    if (_messageHeader.MessageType.TriggerEventCode != _triggerEvent)
                        throw new ParseException("The MessageHeader is not compatible with the current type of message.");
                    if (_messageHeader.MessageType.MessageStructureId != messageStructure)
                        throw new ParseException("The MessageHeader has an invalid MessageStructureId");
                }
                else
                {
                    _messageHeader.MessageType = new CompositeMessageType
                                                     {
                                                         MessageTypeCode = _messageType,
                                                         TriggerEventCode = _triggerEvent,
                                                         MessageStructureId = messageStructure
                                                     };
                }
            }
        }

        #endregion

    }
}
